package com.mochat.mochat.controller.channel;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mochat.mochat.common.annotion.LoginToken;
import com.mochat.mochat.common.em.permission.ReqPerEnum;
import com.mochat.mochat.common.model.RequestPage;
import com.mochat.mochat.common.util.QRCodeUtil;
import com.mochat.mochat.common.util.wm.ApiRespUtils;
import com.mochat.mochat.common.util.wxpay.WXPay;
import com.mochat.mochat.common.util.wxpay.WXPayConfigServer;
import com.mochat.mochat.config.ex.ParamException;
import com.mochat.mochat.dao.entity.UserOrderEntity;
import com.mochat.mochat.dao.entity.channel.ChannelCodeEntity;
import com.mochat.mochat.model.ApiRespVO;
import com.mochat.mochat.model.channel.ReqChannelCodeDTO;
import com.mochat.mochat.model.channel.ReqChannelCodeListDTO;
import com.mochat.mochat.model.channel.ReqChannelCodeStatisticsDTO;
import com.mochat.mochat.model.channel.ReqChannelCodeStatisticsIndexDTO;
import com.mochat.mochat.service.channel.IChannelCodeService;
import com.mochat.mochat.service.impl.IWorkContactEmployeeService;
import com.mochat.mochat.service.userOrder.IUserOrderService;
import org.jdom2.transform.JDOMSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author: yangpengwei
 * @time: 2021/2/22 2:47 下午
 * @description 渠道活码
 */
@RestController
@RequestMapping("/channelCode")
public class ChannelCodeController {

    private final static Logger LOGGER = LoggerFactory.getLogger(ChannelCodeController.class);

    @Autowired
    private IChannelCodeService channelCodeService;

    @Autowired
    private IWorkContactEmployeeService contactEmployeeService;

    @Autowired
    private IUserOrderService userOrderService;

    /**
     * @author: yangpengwei
     * @time: 2021/2/22 3:53 下午
     * @description 新建渠道码
     */
    @PostMapping("/store")
    public ApiRespVO storeCode(@RequestBody ReqChannelCodeDTO req) {
        String name = req.getBaseInfo().getName();
        Integer count = channelCodeService.lambdaQuery().eq(ChannelCodeEntity::getName, name + 1).count();
        if (count>0){
            throw new ParamException("活码名称不能重名");
        }
        String newName = "";
        Integer channelCodeAmount = req.getBaseInfo().getChannelCodeAmount();
        for (Integer i = 1; i < channelCodeAmount + 1; i++) {
            newName = name + i;
            req.getBaseInfo().setName(newName);
            channelCodeService.storeOrUpdateCode(req);
        }
        return ApiRespUtils.getApiRespOfOk();
    }
    @LoginToken
    @GetMapping("/download")
    public void download(HttpServletRequest request, HttpServletResponse response){
        String tagIds = request.getParameter("downloadIds");
        String[] downloadIds = tagIds.split(",");
        List<Integer> ids = new ArrayList<>();
        for(String down: downloadIds){
            ids.add(Integer.valueOf(down));
        }
        channelCodeService.download(ids,request,response);
    }

    /**
     * @author: yangpengwei
     * @time: 2021/2/22 3:53 下午
     * @description 编辑渠道码
     */
    @PutMapping("/update")
    public ApiRespVO updateCode(@RequestBody ReqChannelCodeDTO req) {
        channelCodeService.storeOrUpdateCode(req);
        return ApiRespUtils.getApiRespOfOk();
    }

    /**
     * @author: yangpengwei
     * @time: 2021/2/22 3:53 下午
     * @description 编辑渠道码
     */
    @GetMapping("/show")
    public ApiRespVO showCode(@NotNull(message = "渠道码 id 不能为空") Integer channelCodeId) {
        return ApiRespUtils.getApiRespOfOk(channelCodeService.getChannelCodeDetail(channelCodeId));
    }

    /**
     * @author: jack
     * @time: 2022/4/7
     * @description 编辑渠道商信息
     */
    @GetMapping("/channelBuiness/edit")
    public ApiRespVO editChannelBuiness(@NotNull(message = "渠道码 id 不能为空") Integer channelCodeId,
                                        String channelBusinessName, String channelBusinessPhone) {
        return ApiRespUtils.getApiRespOfOk(channelCodeService.updateChannelBuinessInfo(channelCodeId,channelBusinessName,channelBusinessPhone));
    }

    /**
     * @author: yangpengwei
     * @time: 2021/2/22 3:53 下午
     * @description 查询渠道码
     */
    @GetMapping("/index")
    public ApiRespVO codeList(ReqChannelCodeListDTO req, RequestPage page, @RequestAttribute ReqPerEnum permission) {
        return ApiRespUtils.getApiRespByPage(channelCodeService.getChannelCodePageByReq(req, page, permission));
    }

    /**
     * @author: yangpengwei
     * @time: 2021/2/22 3:53 下午
     * @description 渠道码客户
     */
    @GetMapping("/contact")
    public ApiRespVO codeContactList(@NotNull(message = "渠道码 id 不能为空") Integer channelCodeId, RequestPage page) {
        return ApiRespUtils.getApiRespByPage(channelCodeService.getChannelCodeContactByReq(channelCodeId, page));
    }

    /**
     * @author: yangpengwei
     * @time: 2021/2/22 3:53 下午
     * @description 统计分页数据
     */
    @GetMapping("/statisticsIndex")
    public ApiRespVO getStatisticsOfPage(ReqChannelCodeStatisticsIndexDTO req) {
        req.checkParam();
        return ApiRespUtils.getApiRespByPage(contactEmployeeService.getStatisticsOfPage(req));
    }

    /**
     * @author: yangpengwei
     * @time: 2021/2/22 3:53 下午
     * @description 统计折线图
     */
    @GetMapping("/statistics")
    public ApiRespVO getStatistics(ReqChannelCodeStatisticsDTO req) {
        return ApiRespUtils.getApiRespOfOk(contactEmployeeService.getStatistics(req));
    }

    /**
     * 用户扫码微信支付后，支付回调处理
     * @param reqData
     * @return
     */
    @PostMapping("/wxPayNotify")
    @LoginToken
    public String wxPayNotify(@RequestBody String reqData) throws Exception{
        LOGGER.info("入口" + reqData);
        WXPayConfigServer config = new WXPayConfigServer();
        WXPay wxpay = new WXPay(config);
        System.out.println(reqData);
        Map<String, String> notifyMap = wxpay.processResponseXml(reqData);
        if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
            System.out.println("验签成功");
            // 签名正确
            // 进行处理。
            // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
            // 更新订单表支付状态为已支付
            String out_trade_no = notifyMap.get("out_trade_no");
            System.out.println(out_trade_no);
            LOGGER.info("订单号：" + out_trade_no);
            UpdateWrapper<UserOrderEntity> queryWrapper = new UpdateWrapper<>();
            queryWrapper.eq("out_trade_no",out_trade_no);
            queryWrapper.set("status",1);
            userOrderService.update(queryWrapper);

            // 更新渠道佣金总金额
//            UserOrderEntity userOrderEntity = userOrderService.lambdaQuery().eq(UserOrderEntity::getOutTradeNo, out_trade_no).one();
//            ChannelCodeEntity channelCodeEntity = channelCodeService.getById(userOrderEntity.getChannelCodeId());
//            BigDecimal brokerage = channelCodeEntity.getBrokerage();
//            BigDecimal brokerageScale = channelCodeEntity.getBrokerageScale();
//            brokerage = userOrderEntity.getTotalFee().multiply(brokerageScale.divide(new BigDecimal(100))).add(brokerage);
//            channelCodeEntity.setBrokerage(brokerage);
//            channelCodeService.updateById(channelCodeEntity);

            String response = "<xml>\n" +
                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                    "</xml>";
            return response;
        }
        else {
            LOGGER.info("签名失败");
            System.out.println("验签失败");
            // 签名错误，如果数据里没有sign字段，也认为是签名错误
            String response = "<xml>\n" +
                    "  <return_code><![CDATA[FAIL]]></return_code>\n" +
                    "  <return_msg><![CDATA[FAIL]]></return_msg>\n" +
                    "</xml>";
            return response;
        }
    }

    /**
     * jsapi微信支付后，支付回调处理
     * @param reqData
     * @return
     */
    @PostMapping("/wxPayNotify/jsapi")
    @LoginToken
    public String wxPayNotifyJsapi(@RequestBody String reqData) throws Exception{
        LOGGER.info("入口" + reqData);
        WXPayConfigServer config = new WXPayConfigServer();
        WXPay wxpay = new WXPay(config);

        Map<String, String> notifyMap = wxpay.processResponseXml(reqData);
        if (wxpay.isPayResultNotifySignatureValidNew(notifyMap)) {
            // 签名正确
            // 进行处理。
            // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
            // 更新订单表支付状态为已支付
            String out_trade_no = notifyMap.get("out_trade_no");
            LOGGER.info("订单号：" + out_trade_no);
            UpdateWrapper<UserOrderEntity> queryWrapper = new UpdateWrapper<>();
            queryWrapper.eq("out_trade_no",out_trade_no);
            queryWrapper.set("status",1);
            userOrderService.update(queryWrapper);

            String response = "<xml>\n" +
                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                    "</xml>";
            return response;
        }
        else {
            LOGGER.info("签名失败");
            // 签名错误，如果数据里没有sign字段，也认为是签名错误
            String response = "<xml>\n" +
                    "  <return_code><![CDATA[FAIL]]></return_code>\n" +
                    "  <return_msg><![CDATA[FAIL]]></return_msg>\n" +
                    "</xml>";
            return response;
        }
    }

}
